import {defineStore} from "pinia";
import {nextTick, ref} from "vue";
import {darkTheme, GlobalTheme, SelectOption} from "naive-ui";
import {local, session} from "./storage";
import {Tab} from "../model/Tab";
import router from "../router";
import UserApi from "../api/UserApi";
import {EnumMapStore, EnumOptionStore} from "../model/Common";
import CommonApi from "../api/CommonApi";

export default defineStore("app", {
    state: () => {
        return {
            publicKey: "",
            username: session.getString("username") || "",
            token: session.getString("token") || "",
            reloading: false,
            collapsed: false,
            dark: false,
            tabs: session.get("tabs") || new Array<Tab>(),
            activeTab: session.getString("activeTab") || "",
            enumOptionStore: new EnumOptionStore(),
            enumMapStore: new EnumMapStore()
        }
    },
    getters: {
        theme(state): any {
            return state.dark ? darkTheme : ref<GlobalTheme | null>(null);
        }
    },
    actions: {
        async reloadPage() {
            window.$loadingBar.start();
            this.reloading = true;
            await nextTick();
            this.reloading = false;

            setTimeout(() => {
                document.documentElement.scrollTo({left: 0, top: 0});
                window.$loadingBar.finish();
            }, 100);
        },
        syncPublicKey(): void {
            UserApi.getPublicKey().then(response => {
                this.publicKey = response;
            });
        },
        syncEnumOptionList(): void {
            const args: string[] = [];
            Object.entries(this.enumOptionStore).forEach(([k, v]) => {
                args.push(k);
            });
            CommonApi.enumOptionList(args.join(",")).then(response => {
                this.enumOptionStore = response;
                Object.entries(this.enumOptionStore).forEach(([k, v]) => {
                    const map = new Map<number, string>();
                    v.forEach((val: SelectOption) => {
                        map.set(val.value as number, val.label as string);
                    });
                    this.enumMapStore[k] = map;
                });
            });
        },
        syncDarkLabel(): void {
            const darkLabel = local.getString("dark");
            this.dark = !!(darkLabel && darkLabel.length > 0);
        },
        switchCollapsed(): void {
            this.collapsed = !this.collapsed;
        },
        switchTheme(): void {
            this.dark = !this.dark;
            local.setString("dark", this.dark ? "1" : "");
        },
        setToken(token: string): void {
            this.token = token;
            session.setString("token", token);
        },
        setUsername(username: string): void {
            this.username = username;
            session.setString("username", username);
        },
        clearSession(): void {
            session.clear();
        },
        setActiveTab(path: string): void {
            this.activeTab = path;
            session.setString("activeTab", path);
        },
        setTabs(tabs: Tab[]): void {
            this.tabs = tabs;
            session.set("tabs", tabs);
        },
        addTab(tab: Tab): void {
            this.setActiveTab(tab.path);
            if (this.tabs.some((item: Tab) => item.path === tab.path)) {
                return;
            }
            this.setTabs([...this.tabs, tab]);
        },
        removeTab(path: string): void {
            if (path === this.activeTab) {
                const activeIndex = this.tabs.findIndex((item: Tab) => item.path === path);
                if (activeIndex > 0) {
                    router.push(this.tabs[activeIndex - 1].path);
                } else {
                    router.push(this.tabs[activeIndex + 1].path);
                }
            }
            this.setTabs(this.tabs.filter((item: Tab) => item.path !== path));
        },
        removeOther(curPath: string): void {
            this.setTabs(this.tabs.filter((item: Tab) => item.path === curPath));
            if (curPath !== this.activeTab) {
                router.push(this.tabs[this.tabs.length - 1].path);
            }
        },
        removeLeft(curPath: string): void {
            const curIndex = this.tabs.findIndex((item: Tab) => item.path === curPath);
            const filterTabs = this.tabs.filter((item: Tab, index: number) => index >= curIndex);
            this.setTabs(filterTabs);
            if (!filterTabs.find((item: Tab) => item.path === this.activeTab)) {
                router.push(filterTabs[filterTabs.length - 1].path);
            }
        },
        removeRight(curPath: string): void {
            const curIndex = this.tabs.findIndex((item: Tab) => item.path === curPath);
            const filterTabs = this.tabs.filter((item: Tab, index: number) => index <= curIndex);
            this.setTabs(filterTabs);
            if (!filterTabs.find((item: Tab) => item.path === this.activeTab)) {
                router.push(filterTabs[filterTabs.length - 1].path);
            }
        },
    }
});